const rewire = require('rewire')
const cheerio = require('cheerio')
const R = require('ramda')

function textBy(css) {
    return $ => {
        return replaceHtmlEntities($(css).text()).trim()
    }
}

function attrBy(css, attr) {
    return $ => {
        const aval = $(css).attr(attr)
        if (aval) {
            return aval.trim()
        }
        return ""
    }
}

function mapListBy(css, byFn) {
    return $ => {
        let result = []
        $(css).each(function(i, el) {
            const html = $(el).html()
            result[i] = parse(html, byFn)
        }).toArray()
        return result
    }
}

function composeO(rule) {
    return $ => {
        const keys = R.keys(rule)
        let result = {}
        for (let k of keys) {
            const fn = rule[k]
            result[k] = fn($)
        }
        return result
    }
}

function composeL(...ruleFns) {
    return $ => ruleFns.map(ruleFn => ruleFn($))
}

function parse(html, rule) {
    const $ = cheerio.load(html, {xmlMode: true})
    return rule($)
}

function replaceHtmlEntities(text) {
    var entities = {
        '&nbsp;': ' ',
        '&lt;': '<',
        '&gt;': '>',
        '&amp;': '&',
        '&quot;': '\"',
        '&#39;': '\''
    };
    var reg = new RegExp('(' + Object.keys(entities).join('|') + ')', 'g');
    text = text.replace(reg, function(match) {
        return entities[match];
    });
    return text;
}

module.exports = {
    textBy,
    attrBy,
    mapListBy,
    composeO,
    composeL,
    parse,
    replaceHtmlEntities
}